import tkinter as tk
from tkinter import ttk, messagebox, filedialog, simpledialog
import pandas as pd
import datetime
import os
import openpyxl
from openpyxl.utils.dataframe import dataframe_to_rows

from inventory_management import InventoryManagement
from report_generation import ReportGeneration
from user_management import UserManagement


class Application(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("个人库存与任务管理器")
        self.user_management = UserManagement()
        self.inventory_management = InventoryManagement()
        self.report_generation = ReportGeneration()
        self.current_user = None
        self.show_login_page()

    def show_login_page(self):
        for widget in self.winfo_children():
            widget.destroy()

        self.login_frame = tk.Frame(self)
        self.login_frame.pack(pady=20)

        self.username_label = tk.Label(self.login_frame, text="用户名:")
        self.username_entry = tk.Entry(self.login_frame)
        self.password_label = tk.Label(self.login_frame, text="密码:")
        self.password_entry = tk.Entry(self.login_frame, show="*")

        self.login_button = tk.Button(self.login_frame, text="登录", command=self.login)
        self.register_button = tk.Button(self.login_frame, text="注册", command=self.register)

        self.username_label.grid(row=0, column=0, padx=5, pady=5)
        self.username_entry.grid(row=0, column=1, padx=5, pady=5)
        self.password_label.grid(row=1, column=0, padx=5, pady=5)
        self.password_entry.grid(row=1, column=1, padx=5, pady=5)
        self.login_button.grid(row=2, column=0, columnspan=2, pady=10)
        self.register_button.grid(row=3, column=0, columnspan=2, pady=10)

    def login(self):
        username = self.username_entry.get()
        password = self.password_entry.get()
        success, message, role = self.user_management.login_user(username, password)
        if success:
            self.current_user = username
            self.show_main_menu(role)
        else:
            messagebox.showerror("错误", message)

    def register(self):
        username = simpledialog.askstring("输入", "请输入用户名")
        password = simpledialog.askstring("输入", "请输入密码")
        success, message = self.user_management.register_user(username, password)
        if success:
            messagebox.showinfo("成功", message)
        else:
            messagebox.showerror("错误", message)

    def show_main_menu(self, role):
        for widget in self.winfo_children():
            widget.destroy()

        self.menu_bar = tk.Menu(self)
        self.config(menu=self.menu_bar)

        # 主菜单
        self.file_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="文件", menu=self.file_menu)
        self.file_menu.add_command(label="退出", command=self.quit)

        self.inventory_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="库存管理", menu=self.inventory_menu)
        self.inventory_menu.add_command(label="添加物品", command=self.add_item)
        self.inventory_menu.add_command(label="导入物品", command=self.import_items)
        self.inventory_menu.add_command(label="查看物品", command=self.view_items)

        # 任务管理菜单
        self.task_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="任务管理", menu=self.task_menu)
        self.task_menu.add_command(label="新建盘点单", command=self.create_inventory_check)
        self.task_menu.add_command(label="盘点单查询", command=self.query_inventory_check)
        self.task_menu.add_command(label="效期登记", command=self.expiration_registration)

        self.report_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="报表生成", menu=self.report_menu)
        self.report_menu.add_command(label="生成报表", command=self.generate_reports)

        self.user_menu = tk.Menu(self.menu_bar, tearoff=0)
        self.menu_bar.add_cascade(label="用户", menu=self.user_menu)
        self.user_menu.add_command(label="注销", command=self.logout)
        if role == 'admin':
            self.user_menu.add_command(label="管理员选项", command=self.show_admin_menu)

    def add_item(self):
        item_code = simpledialog.askinteger("输入", "物品编号")
        item_name = simpledialog.askstring("输入", "物品名称")
        unit = simpledialog.askstring("输入", "物品单位")
        retail_price = simpledialog.askfloat("输入", "零售价")
        specification = simpledialog.askstring("输入", "商品规格")
        additional_info = simpledialog.askstring("输入", "扩展信息")
        if all([item_code, item_name, unit, retail_price, specification, additional_info]):
            self.inventory_management.add_item(item_code, item_name, unit, retail_price, specification, additional_info)
            messagebox.showinfo("成功", "物品添加成功")
        else:
            messagebox.showerror("错误", "请填写所有必填项")

    def import_items(self):
        success, message = self.inventory_management.import_items()
        if success:
            messagebox.showinfo("成功", message)
        else:
            messagebox.showerror("错误", message)

    def view_items(self):
        items = self.inventory_management.get_items()
        self.show_treeview_window(items)

    def show_treeview_window(self, items):
        treeview_window = tk.Toplevel(self)
        treeview_window.title("库存物品列表")

        columns = ("商品编号", "商品名称", "商品单位", "零售价", "商品规格", "扩展信息")
        tree = ttk.Treeview(treeview_window, columns=columns, show='headings')

        for col in columns:
            tree.heading(col, text=col)
            tree.column(col, width=100)

        for item in items:
            tree.insert("", "end", values=(item['商品编号'], item['商品名称'], item['商品单位'], item['零售价'], item['商品规格'], item['扩展信息']))

        tree.bind("<Double-1>", lambda event: self.update_item_gui(tree))
        tree.bind("<Button-3>", lambda event: self.show_context_menu(event, tree))

        # 添加查询功能
        search_frame = tk.Frame(treeview_window)
        search_frame.pack(pady=10)

        self.search_entry = tk.Entry(search_frame)
        self.search_button = tk.Button(search_frame, text="查询", command=lambda: self.search_items(tree))

        self.search_entry.pack(side=tk.LEFT, padx=5)
        self.search_button.pack(side=tk.LEFT, padx=5)

        tree.pack(fill=tk.BOTH, expand=True)

    def search_items(self, tree):
        query = self.search_entry.get().strip()
        if query:
            items = self.inventory_management.get_items()
            filtered_items = [item for item in items if any(query.lower() in str(value).lower() for value in item.values())]
            self.refresh_treeview(tree, filtered_items)
        else:
            items = self.inventory_management.get_items()
            self.refresh_treeview(tree, items)

    def refresh_treeview(self, tree, items):
        for i in tree.get_children():
            tree.delete(i)
        for item in items:
            tree.insert("", "end", values=(item['商品编号'], item['商品名称'], item['商品单位'], item['零售价'], item['商品规格'], item['扩展信息']))

    def update_item_gui(self, tree):
        selected_item = tree.selection()
        if selected_item:
            item_values = tree.item(selected_item)['values']
            item_code, item_name, unit, retail_price, specification, additional_info = item_values

            update_window = tk.Toplevel(self)
            update_window.title("更新物品信息")

            self.item_code_entry = tk.Entry(update_window, state='readonly')
            self.item_code_entry.insert(0, item_code)
            self.item_name_entry = tk.Entry(update_window)
            self.item_name_entry.insert(0, item_name)
            self.unit_entry = tk.Entry(update_window)
            self.unit_entry.insert(0, unit)
            self.retail_price_entry = tk.Entry(update_window)
            self.retail_price_entry.insert(0, retail_price)
            self.specification_entry = tk.Entry(update_window)
            self.specification_entry.insert(0, specification)
            self.additional_info_entry = tk.Entry(update_window)
            self.additional_info_entry.insert(0, additional_info)

            self.save_button = tk.Button(update_window, text="保存", command=lambda: self.save_updated_item(item_code, tree, update_window))

            self.item_code_entry.grid(row=0, column=1, padx=5, pady=5)
            self.item_name_entry.grid(row=1, column=1, padx=5, pady=5)
            self.unit_entry.grid(row=2, column=1, padx=5, pady=5)
            self.retail_price_entry.grid(row=3, column=1, padx=5, pady=5)
            self.specification_entry.grid(row=4, column=1, padx=5, pady=5)
            self.additional_info_entry.grid(row=5, column=1, padx=5, pady=5)
            self.save_button.grid(row=6, column=1, padx=5, pady=5)

            labels = ["商品编号:", "商品名称:", "商品单位:", "零售价:", "商品规格:", "扩展信息:"]
            for i, label in enumerate(labels):
                tk.Label(update_window, text=label).grid(row=i, column=0, padx=5, pady=5)

    def save_updated_item(self, item_code, tree, window):
        item_name = self.item_name_entry.get()
        unit = self.unit_entry.get()
        retail_price = self.retail_price_entry.get()
        specification = self.specification_entry.get()
        additional_info = self.additional_info_entry.get()

        if all([item_name, unit, retail_price, specification, additional_info]):
            success, message = self.inventory_management.update_item(item_code, 商品名称=item_name, 商品单位=unit, 零售价=float(retail_price), 商品规格=specification, 扩展信息=additional_info)
            if success:
                messagebox.showinfo("成功", message)
                window.destroy()
                self.refresh_treeview(tree, self.inventory_management.get_items())
            else:
                messagebox.showerror("错误", message)
        else:
            messagebox.showerror("错误", "请填写所有必填项")

    def show_context_menu(self, event, tree):
        selected_item = tree.selection()
        if selected_item:
            context_menu = tk.Menu(self, tearoff=0)
            context_menu.add_command(label="删除", command=lambda: self.confirm_delete_item(selected_item, tree))
            context_menu.post(event.x_root, event.y_root)

    def confirm_delete_item(self, selected_item, tree):
        item_values = tree.item(selected_item)['values']
        item_code = item_values[0]

        result = messagebox.askyesno("确认删除", f"确定要删除编号为 {item_code} 的物品吗？")
        if result:
            success, message = self.inventory_management.delete_item(item_code)
            if success:
                messagebox.showinfo("成功", message)
                tree.delete(selected_item)
            else:
                messagebox.showerror("错误", message)

    def generate_reports(self):
        self.report_generation.generate_inventory_report()
        self.report_generation.generate_task_report()
        messagebox.showinfo("成功", "报表生成成功")

    def logout(self):
        self.current_user = None
        self.show_login_page()

    def show_admin_menu(self):
        for widget in self.winfo_children():
            widget.destroy()

        self.manage_users_button = tk.Button(self, text="管理用户", command=self.manage_users)
        self.back_button = tk.Button(self, text="返回", command=self.show_main_menu)

        self.manage_users_button.pack(pady=10)
        self.back_button.pack(pady=10)

    def manage_users(self):
        # 这里可以添加管理用户的功能，例如添加、删除、修改用户
        pass

    def create_inventory_check(self):
        file_path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx *.xls")])
        if file_path:
            try:
                df = pd.read_excel(file_path)
                date_str = datetime.datetime.now().strftime("%Y%m%d")
                file_name = f"{date_str}_盘点单.xlsx"
                inventory_check_dir = "inventory_checks"

                # 确保目录存在
                if not os.path.exists(inventory_check_dir):
                    os.makedirs(inventory_check_dir)

                file_path = os.path.join(inventory_check_dir, file_name)
                df.to_excel(file_path, index=False)

                # 创建有效期登记工作表
                expiration_file_name = f"有效期登记_{date_str}.xlsx"
                expiration_file_path = os.path.join("Valid_period", expiration_file_name)
                if not os.path.exists("Valid_period"):
                    os.makedirs("Valid_period")
                df['有效期'] = ''  # 添加有效期列
                wb = openpyxl.Workbook()
                ws = wb.active
                for r in dataframe_to_rows(df, index=False, header=True):
                    ws.append(r)
                wb.save(expiration_file_path)

                messagebox.showinfo("成功", f"盘点单 {file_name} 及有效期登记表 {expiration_file_name} 已成功导入")
            except Exception as e:
                messagebox.showerror("错误", f"导入失败: {str(e)}")

    def query_inventory_check(self):
        inventory_check_window = tk.Toplevel(self)
        inventory_check_window.title("盘点单查询")

        columns = ("文件名", "导入日期")
        tree = ttk.Treeview(inventory_check_window, columns=columns, show='headings')

        for col in columns:
            tree.heading(col, text=col)
            tree.column(col, width=150)

        # 获取盘点单文件列表
        inventory_check_dir = "inventory_checks"
        if not os.path.exists(inventory_check_dir):
            os.makedirs(inventory_check_dir)

        files = os.listdir(inventory_check_dir)
        files = [f for f in files if f.endswith(".xlsx")]
        files.sort(reverse=True)  # 按日期倒序排列

        for file in files:
            file_path = os.path.join(inventory_check_dir, file)
            modified_time = os.path.getmtime(file_path)
            modified_date = datetime.datetime.fromtimestamp(modified_time).strftime("%Y-%m-%d %H:%M:%S")
            tree.insert("", "end", values=(file, modified_date))

        tree.bind("<Double-1>", lambda event: self.show_inventory_check_details(tree))

        tree.pack(fill=tk.BOTH, expand=True)

    def show_inventory_check_details(self, tree):
        selected_item = tree.selection()
        if selected_item:
            file_name = tree.item(selected_item)['values'][0]
            file_path = os.path.join("inventory_checks", file_name)
            try:
                df = pd.read_excel(file_path)
                details_window = tk.Toplevel(self)
                details_window.title(f"盘点单详情: {file_name}")

                columns = list(df.columns)
                tree_details = ttk.Treeview(details_window, columns=columns, show='headings')

                for col in columns:
                    tree_details.heading(col, text=col)
                    tree_details.column(col, width=150)

                for index, row in df.iterrows():
                    tree_details.insert("", "end", values=list(row))

                tree_details.pack(fill=tk.BOTH, expand=True)
            except Exception as e:
                messagebox.showerror("错误", f"读取盘点单失败: {str(e)}")

    def expiration_registration(self):
        valid_period_dir = "Valid_period"
        if not os.path.exists(valid_period_dir):
            os.makedirs(valid_period_dir)

        files = [f for f in os.listdir(valid_period_dir) if f.startswith("有效期登记_") and f.endswith(".xlsx")]
        if not files:
            messagebox.showwarning("警告", "没有找到有效期登记表")
            return

        latest_file = max(files, key=lambda x: os.path.getmtime(os.path.join(valid_period_dir, x)))
        file_path = os.path.join(valid_period_dir, latest_file)

        try:
            wb = openpyxl.load_workbook(file_path)
            ws = wb.active
            data = []
            headers = [cell.value for cell in ws[1]]
            for row in ws.iter_rows(min_row=2, values_only=True):
                data.append(row)

            self.show_expiration_treeview(headers, data, file_path)
        except Exception as e:
            messagebox.showerror("错误", f"读取有效期登记表失败: {str(e)}")

    def show_expiration_treeview(self, headers, data, file_path):
        expiration_window = tk.Toplevel(self)
        expiration_window.title("有效期登记")

        columns = headers
        tree = ttk.Treeview(expiration_window, columns=columns, show='headings')

        for col in columns:
            tree.heading(col, text=col)
            tree.column(col, width=150)

        for row in data:
            tree.insert("", "end", values=row)

        # 设置有效期列可编辑
        tree.bind('<Double-1>', lambda event: self.on_cell_click(event, tree))

        # 添加提交按钮
        submit_button = tk.Button(expiration_window, text="提交", command=lambda: self.submit_expiration_data(tree, file_path))
        submit_button.pack(pady=10)

        tree.pack(fill=tk.BOTH, expand=True)

    def on_cell_click(self, event, tree):
        item = tree.identify_row(event.y)
        column = tree.identify_column(event.x)
        if column == '#7':  # 假设有效期是第7列
            entry = tk.Entry(tree)
            entry.place(x=event.x, y=event.y, anchor='nw', width=150)
            entry.insert(0, tree.set(item, column))
            entry.focus_set()
            entry.bind('<Return>', lambda event: self.on_entry_confirm(event, tree, item, column, entry))
            entry.bind('<Escape>', lambda event: entry.destroy())

    def on_entry_confirm(self, event, tree, item, column, entry):
        value = entry.get()
        tree.set(item, column, value)
        entry.destroy()

    def submit_expiration_data(self, tree, file_path):
        data = []
        for child in tree.get_children():
            values = tree.item(child)['values']
            data.append(values)

        wb = openpyxl.load_workbook(file_path)
        ws = wb.active
        for i, row in enumerate(data, start=2):
            for j, value in enumerate(row, start=1):
                ws.cell(row=i, column=j, value=value)

        wb.save(file_path)
        messagebox.showinfo("成功", "有效期数据已提交")

if __name__ == "__main__":
    app = Application()
    app.mainloop()